// import LogFactory from "@/log/LogFactory.ts";
import type {Router as RemixRouter} from "@remix-run/router/dist/router";
import {IRouter, RouteConfig} from "@/route/index";
import React, {Suspense} from "react";
import {createBrowserRouter, RouteObject} from "react-router-dom";
import IndexPage from "@/route/IndexPage.tsx";
import LoadingComponent from "@/common/loading/LoadingComponent.tsx";
// import ErrorComponent from "@/common/ErrorComponent.tsx";

// const log = LogFactory.getLogger("RouteResolve");

/**
 * 自动路由解析器
 */
export default class RouteResolve {
    private readonly elements = import.meta.glob("@/page/**/*.tsx", {
        eager: false
    });
    private readonly configs = import.meta.glob("@/page/**/config.ts", {
        eager: true,
        // import: "default"
        import: "config"
    });
    /**
     * 路由配置key正则表达式
     */
    private readonly configKeyRegExp = new RegExp("[A-Z][a-z]+([A-Z][a-z]+)?Page.tsx");
    /**
     * 路由路径正则表达式
     */
    private readonly pathRegExp = new RegExp("/[A-Z][a-z]+([A-Z][a-z]+)?Page.tsx");

    /**
     * 一级路由路径正则表达式
     */
    private readonly firstPathRegExp = new RegExp("^\\/[^/]*$");

    /** 匹配全部路由中的一级路由的正则 */
    // 找到路径中只有一个/的路径,一级路径
    // ^: 匹配字符串的开始位置
    // \/: 匹配一个 / 字符
    // [^\/]+: 匹配除了 / 之外的任意字符，+ 表示至少匹配一个字符
    // $: 匹配字符串的结束位置
    // private readonly REG_MAIN_PATH: RegExp = /^\/[^\/]+$/;

    /**
     * 获取路由器 RemixRouter
     */
    public getRemixRouter(): RemixRouter {
        const routeInfos: IRouter[] = Object.entries(this.elements)
            .map(([key, ele]) => {
                const configKey = key.replace(this.configKeyRegExp, "config.ts");
                const pathKey = key.replace("/src/page", "").replace(this.pathRegExp, "");
                return {
                    config: this.configs[configKey] as RouteConfig,
                    path: pathKey,
                    element: this.lazyLoadedComponent(ele),
                    isMainRoute: pathKey.match(this.firstPathRegExp) !== null
                }
            });
        const mainRoutes = routeInfos.filter(r => r.isMainRoute);
        const childRoutes = routeInfos.filter(r => !r.isMainRoute);
        const routers = mainRoutes.map(e => this.parseConvertRoute(e, childRoutes));
        // console.log("最终路由信息: ", routers);
        const future = {
            v7_fetcherPersist: true,
            v7_partialHydration: true,
            v7_normalizeFormMethod: true,
            v7_relativeSplatPath: true,
            v7_skipActionErrorRevalidation: true,
        }
        return createBrowserRouter([
            {
                path: "/",
                element: <IndexPage/>,
                // children: routers,
                // errorElement: <ErrorComponent/>
            },
            ...routers
            // {
            //     path: "*",
            //     element: <Navigate to={"/404"}/>
            // }
        ],{future});

    }
    /**
     * 解析路由信息并转换为React-Router-Dom的RouteObject
     */
    private parseConvertRoute(route: IRouter, routes: IRouter[]): RouteObject {
        const {config, path, element} = route;
        const index: boolean = config?.index || path.includes("index")
        const children = this.findChildRoute(path, routes);
        if (index) {
            return {
                index: true,
                element: element,
            };
        } else {
            return {
                path: path,
                element: element,
                children: children
            }
        }
    }
    /**
     * 加载子路由
     */
    private findChildRoute(path_: string, routes: IRouter[]): RouteObject[] {
        // 找到路由路径_path,的直接子路由
        return routes.filter(e => e.path?.match(new RegExp("^" + path_ + "/[a-z]+$")) !== null)
            .map(e => {
                const {config, path, element} = e;
                const index: boolean = config?.index || path.includes("index");
                const children = this.findChildRoute(path, routes);
                if (index) {
                    return {
                        index: true,
                        element: element,
                    };
                } else {
                    return {
                        path: path,
                        element: element,
                        children: children
                    }
                }
            });
    }
    /**
     * 路由懒加载组件方法
     * @param element 需要懒加载组件
     */
    private lazyLoadedComponent(element: () => Promise<any>) {
        const Temp = React.lazy(() => element());
        return (
            <Suspense fallback={<LoadingComponent/>}>
                <Temp/>
            </Suspense>
        )
    }
}